import { IEvent, IAppState } from "./model";
import { dispatch as winDispatch } from './window-state';
import { dispatch as menusDispatch } from './menus-state';
import { dispatch as filesDispatch } from './files-state';
import { dispatch as editorsDispatch } from './editors-state';
import { dispatch as frameDispatch } from './frame-state';

let appState: IAppState = {
  windowState: null,
  menusState: null,
  filesState: null,
  editorsState: null,
  frameState: null,
};
let didUpdatedCbs: ((s: IAppState) => void)[] = [];

dispatch({ type: 'app.init' });

export function dispatch (e: IEvent) {
  const { windowState, menusState, filesState, editorsState, frameState } = appState;
  appState = {
    ...appState,
    windowState: winDispatch(e, windowState),
    menusState: menusDispatch(e, menusState),
    filesState: filesDispatch(e, filesState),
    editorsState: editorsDispatch(e, editorsState),
    frameState: frameDispatch(e, frameState)
  };
  didUpdatedCbs.forEach(cb => {
    try {
      cb(appState);
    } catch (e) {
      console.error(e);
    }
  });
}

export function didUpdated (cb: (s: IAppState) => void): (() => void) {
  didUpdatedCbs.push(cb);
  return () => {
    didUpdatedCbs = didUpdatedCbs.filter(o => o != cb);
  };
}

export function getAppState (): IAppState {
  return appState;
}

(window as any).getAppState = getAppState;